home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / security / passwd+ / log.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-12  |  6.2 KB  |  313 lines

  1. /*
  2.  * this file contains ALL the logging routines
  3.  */
  4. #include "passwd.h"
  5.  
  6. /*
  7.  * these are keywords for log levels
  8.  */
  9. struct logkey {
  10.     char *word;        /* what the user types */
  11.     int wlen;        /* how long it is */
  12.     unsigned short level;    /* what bit to set */
  13. } levels[] = {
  14.     { "syntax",    6,    LG_SYNTAX,    },
  15.     { "use",    3,    LG_USE,        },
  16.     { "result",    6,    LG_RESULT,    },
  17.     { "item",    4,    LG_ITEM,    },
  18.     { "debug",    5,    LG_DEBUG,    },
  19.     { "system",    6,    LG_SYSTEM,    },
  20.     { "all",    3,    LG_ALL,        },
  21.     { CH_NULL,    0,    LG_NONE,    },
  22. };
  23.  
  24. /*
  25.  * each log gets an entry like this
  26.  */
  27. struct loginfo {
  28.     unsigned short log;        /* what is being logged (level) */
  29.     char *loc;            /* whee it is going to */
  30.     FILE *locp;            /* file pointer if needed */
  31.     unsigned short flags;        /* generic flag describing loc */
  32. } logto[MAXLOGTO];
  33. static int nlogto = 0;            /* number of logs being used */
  34.  
  35. /*
  36.  * initialize the logging
  37.  */
  38. initlog()
  39. {
  40.     beginlog(LG_INIT);
  41. }
  42.  
  43. /*
  44.  * load the logging level
  45.  */
  46. beginlog(line)
  47. char *line;
  48. {
  49.     register unsigned short logwhat;/* what is to be logged */
  50.     register int sgn;        /* 1 if number is negative */
  51.     register struct logkey *lp;    /* walks logging list */
  52.     register int i;            /* counter in a for loop */
  53.     char *l1;            /* pointer in a for loop */
  54.  
  55.     /*
  56.      * clobber any new line and set up default logging
  57.      */
  58.     if (line[i = strlen(line)-1] == '\n')
  59.         line[i] = '\0';
  60.     logwhat = LG_DEFAULT;
  61.  
  62.     /*
  63.      * skip leading blanks and if nothing, quit
  64.      */
  65.     while(isspace(*line))
  66.         line++;
  67.     if (!*line)
  68.         return;
  69.     /*
  70.      * now just walk the line
  71.      */
  72.     while(*line){
  73.         /*
  74.          * skip leading blanks and commas
  75.          */
  76.         while(*line == ' ' || *line == ',')
  77.             line++;
  78.         /*
  79.          * if at the end of the types, drop out
  80.          */
  81.         if (*line == '\t' || *line == '\0')
  82.             break;
  83.         /*
  84.          * is it negation?
  85.          */
  86.         sgn = 0;
  87.         if (*line == '!'){
  88.             sgn = 1;
  89.             line++;
  90.         }
  91.         /*
  92.          * look for the special case "clear"
  93.          */
  94.         if (strncmp(line, "clear", 5) == 0 && log_end(line[5])){
  95.             if (!sgn)
  96.                 log_reset(logwhat, LG_ALL);
  97.             line = &line[5];
  98.             continue;
  99.         }
  100.         /*
  101.          * see if the word matches anything
  102.          */
  103.         for(lp = levels; lp->word != CH_NULL; lp++)
  104.             if (strncmp(line, lp->word, lp->wlen) == 0 &&
  105.                         !isalnum(line[lp->wlen])){
  106.                 if (sgn)
  107.                     log_reset(logwhat, lp->level);
  108.                 else
  109.                     log_set(logwhat, lp->level);
  110.                 line = &line[lp->wlen];
  111.                 break;
  112.             }
  113.         /*
  114.          * unknown option
  115.          */
  116.         if (lp->word == CH_NULL){
  117.             while(*line && !isspace(*line) && *line != ',')
  118.                 line++;
  119.         }
  120.     }
  121.     /*
  122.      * fake an output if there is none
  123.      */
  124.     if (*line == '\0')
  125.         line = LG_OUTDEF;
  126.     /*
  127.      * now go for the output
  128.      */
  129.     while(isspace(*line))
  130.         line++;
  131.     /*
  132.      * see if it's already used
  133.      */
  134.     for(l1 = &line[1]; isspace(*l1); l1++);
  135.     for(i = 0; i < nlogto; i++){
  136.         if (logto[i].loc[0] != *line)
  137.             continue;
  138.         if (strcmp(&logto[i].loc[1], l1) == 0)
  139.             break;
  140.     }
  141.     /*
  142.      * it is
  143.      */
  144.     if (i != nlogto){
  145.         /*
  146.          * if cleared, close it
  147.          */
  148.         if (logwhat == LG_NONE){
  149.             endlogging(i);
  150.             return;
  151.         }
  152.         /*
  153.          * if now logging LG_USE, say so
  154.          */
  155.         if (log_test(logwhat, LG_USE) &&
  156.                 !log_test(logto[i].log, LG_USE)){
  157.             char tbuf[BUFSIZ];
  158.             SPRINTF(tbuf,
  159.                "run by %s on account %s, password file %s, configuration file %s",
  160.                         runner, user, pwdfile, pwtest);
  161.             logout(i, tbuf);
  162.         }
  163.         /*
  164.          * change the flags and quit
  165.          */
  166.         logto[i].log = logwhat;
  167.         return;
  168.     }
  169.     /*
  170.      * if you're clearing something not set, you're done!
  171.      */
  172.     if (logwhat == LG_NONE)
  173.         return;
  174.     /*
  175.      * new log
  176.      */
  177.     if (strncmp("stderr", line, 6) == 0){    /* standard error */
  178.         logto[nlogto].locp = stderr;
  179.         logto[nlogto].flags = LG_STDERR;
  180.         line++;
  181.     }
  182.     else if (strncmp("syslog", line, 6) == 0){    /* syslog */
  183.         OPENLOG(progname, LOG_PID, LOG_USER);
  184.         logto[nlogto].locp = stderr;
  185.         logto[nlogto].flags = LG_SYSLOG;
  186.         line++;
  187.     }
  188.     else if (*line == '|'){            /* to a program */
  189.         line++;
  190.         while(isspace(*line))
  191.             line++;
  192.         logto[nlogto].locp = popen(line, "w");
  193.         logto[nlogto].flags = LG_PIPE;
  194.         line[-1] = '|';
  195.     }
  196.     else if (*line == '>'){            /* to a file */
  197.         line++;
  198.         while(isspace(*line))
  199.             line++;
  200.         logto[nlogto].locp = fopen(line, "a");
  201.         logto[nlogto].flags = LG_FILE;
  202.         line[-1] = '>';
  203.     }
  204.     else{                    /* ??? */
  205.         LOG2(LG_SYNTAX,
  206.            "bad location to log to on line %d (at \"%s\")",
  207.             linect, line);
  208.         return;
  209.     }
  210.     /*
  211.      * can't open a program or a file
  212.      */
  213.     if (logto[nlogto].locp == FI_NULL){
  214.         LOG2(LG_SYSTEM, "cannot log to \"%s\" on line %d",
  215.                             line, linect);
  216.         return;
  217.     }
  218.     /*
  219.      * save where it's going to be logged
  220.      * and what is to be logged
  221.      */
  222.     logto[nlogto].loc = strsave(line-1);
  223.     logto[nlogto].log = logwhat;
  224.  
  225.     /*
  226.      * if logging use,
  227.      * announce who's doing the dirty deed
  228.      */
  229.     if (log_test(logto[nlogto].log, LG_USE)){
  230.         char tbuf[BUFSIZ];
  231.         SPRINTF(tbuf, "run by %s on account %s, password file %s",
  232.                             runner, user, pwdfile);
  233.         logout(nlogto, tbuf);
  234.     }
  235.     /*
  236.      * one more item to be logged
  237.      */
  238.     nlogto++;
  239. }
  240.  
  241. /*
  242.  * logging function
  243.  */
  244. logfunc(flag, str)
  245. unsigned int flag;        /* what this is */
  246. char *str;            /* log message */
  247. {
  248.     register int i;            /* counter in a for loop */
  249.  
  250.     /*
  251.      * log the message in all appropriate logs
  252.      */
  253.     for(i = 0; i < nlogto; i++)
  254.         if (log_test(logto[i].log, flag))
  255.             logout(i, str);
  256. }
  257.  
  258. /*
  259.  * does the actual logging for one log
  260.  */
  261. logout(logno, str)
  262. int logno;            /* log number */
  263. char *str;            /* mesage */
  264. {
  265.     /*
  266.      * syslog is treated special if SYSLOG is defined
  267.      * the rest just go out
  268.      */
  269. #ifdef SYSLOG
  270.     if (logto[logno].flags == LG_SYSLOG)
  271.         syslog(LOG_INFO, str);
  272.     else
  273. #endif
  274.         FPRINTF(logto[logno].locp, "%s(%5d): %s\n",
  275.                         progname, getpid(), str);
  276. }
  277.  
  278. /*
  279.  * close a log
  280.  */
  281. endlogging(logno)
  282. int logno;                /* log number */
  283. {
  284.     /*
  285.      * closing the specific log depends on what it is
  286.      */
  287.     switch(logto[logno].flags){
  288.     case LG_STDERR:            /* NEVER close stderr! */
  289.         break;
  290. #ifdef SYSLOG
  291.     case LG_SYSLOG:            /* break connection on syslog() */
  292.         closelog();
  293.         break;
  294. #endif
  295.     case LG_PIPE:            /* close pipe for program */
  296.         (void) pclose(logto[logno].locp);
  297.         break;
  298.     case LG_FILE:            /* close file for file */
  299.         (void) fclose(logto[logno].locp);
  300.         break;
  301.     }
  302.     /*
  303.      * now delete the log entry by moving the final
  304.      * one over it (if there is another log)
  305.      */
  306.     if (nlogto--> 1){
  307.         logto[logno].log = logto[nlogto].log;
  308.         logto[logno].loc = logto[nlogto].loc;
  309.         logto[logno].locp = logto[nlogto].locp;
  310.         logto[logno].flags = logto[nlogto].flags;
  311.     }
  312. }
  313.